#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import socket
import threading

#----------------------------------------------------------------------
def proxy_handler(client_socket,remote_host,remote_port,receive_first):

    """处理监听到的请求"""
    
    # 链接远程主机
    remote_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    remote_socket.connect((remote_host,remote_port))
    
    # 如果必要从远程主机接受数据
    if receive_first:
        remote_buffer = receive_from(remote_socket)
        #hexduom(remote_buffer)
        
        # 发送给我们的响应处理
        remote_buffer = resposne_handler(remote_buffer)
        
        # 如果我们有数据传递给本地客户端，发送它
        if len(remote_buffer):
            print "[<==] Sending %d bytes to localhost." % len(remote_buffer)
            
    #　现在我们从本地循环读取数据，发送给远程主机和本地主机
    while True:
        # 从本地读取数据
        local_buffer = receive_from(client_socket)
        
        if len(local_buffer):
            print "[==>] Received %d bytes from localhost." % len(local_buffer)
            #hexduom(local_buffer)
            
        # 发送给我们的本地请求
        local_buffer = request_handler(local_buffer)
    
        # 向远程主机发送数据
        remote_socket.send(local_buffer)
        print "[==>] Sent to remote."
        
        # 接收响应数据
        remote_buffer = receive_from(remote_socket)
    
    if len(remote_buffer):
        
        print "[<==] Received %d bytes from remote." % len(remote_buffer)
        #hexduom(remote_buffer)
        
        #　发送到响应处理函数
        remote_buffer = resposne_handler(remote_buffer)
        
        # 将响应发送给本地socket
        client_socket.send(remote_buffer)
        
        print "[<==] Send to localhost."
        
    # 如果两边都没有数据，关闭链接
    if not len(local_buffer) or not len(remote_buffer):
        client_socket.close()
        remote_socket.close()
        print "[*] No more data. Closing connections."
        
        break
    

# tcp 服务端
def server_loop(local_host,local_port,remote_host,remote_port,receive_first):
    
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    
    try:
        server.bind((local_host,local_port))
    except:
        print "[!!] Failed to listen on %s:%d" % (local_host,local_port)
        sys.exit(0)
        
    print "[*] Listening on %s:%d" % (local_host,local_port)
    
    server.listen(5)
    
    while True:
        client_socket, addr = server.accept()
        
        # 打印数据
        print "[==>] Received incoming connection from %s:%d" % (addr[0],addr[1])
        
        # 开启一个线程与远程主机通信
        proxy_thread = threading.thread(target=proxy_handler,args=(client_socket,remote_host,remote_port,receive_first))
        proxy_thread.start()

# main
#----------------------------------------------------------------------
def main():
    """主体函数"""
    
    # 参数个数错误
    if len(sys.argv[1:]) != 5:
        print "Usage: ./proxy.py [localhost] [localport] [remotehost] [remoteport] [receive_first]"
        print "Example: ./proxy.py 127.0.0.1 9000 10.12.132.1 9000 true"
        sys.exit(0)
        
    # 设置本地监听参数
    local_host = sys.argv[1]
    local_port = int(sys.argv[2])
    
    # 设置远程目标
    remote_host = sys.argv[3]
    remote_port = int(sys.argv[4])
    
    # 告诉代理在发送给远程主机之前链接和接收数据
    if "True" in receive_first:
        receive_first = True
    else:
        receive_first - False
    
    # 现在设置好我们的监听socket
    server_loop(local_host,local_port,remote_host,remote_port,receive_first)
    